home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-24 | 6.8 KB | 236 lines | [TEXT/MMCC] |
- // ===========================================================================
- // CCustomListBox.h ©1994 Jan Bruyndonckx All rights reserved.
- // v1.0 18/6/94
- //
- // A listbox subclass containing custom data.
- // The default listbox contains only string data.
- // ===========================================================================
-
- #include <MixedMode.h>
- #include "CCustomListBox.h"
-
- #ifndef DEBUG_NEW // MetroWerks 'new' leak-finder
- #define NEW new
- #endif
-
- //----------------------------------------------------------------------------
-
- ListDefUPP CCustomListBox::callerLDEFUPP = NULL ;
-
- //----------------------------------------------------------------------------
- // Creation methods. We have to supply these, so that the base class knows
- // which instance to generate when reading from the resource.
-
- CCustomListBox* CCustomListBox::CreateFromStream(LStream *inStream)
- {
- return (NEW CCustomListBox(inStream));
- }
-
- CCustomListBox::CCustomListBox() : LListBox()
- {
- init () ;
- }
-
- CCustomListBox::CCustomListBox(const SPaneInfo &inPaneInfo,
- Boolean inHasHorizScroll, Boolean inHasVertScroll,
- Boolean inHasGrow, Boolean inHasFocusBox,
- MessageT inDoubleClickMessage, Int16 inTextTraitsID,
- LCommander *inSuper) :
- LListBox (inPaneInfo, inHasHorizScroll, inHasVertScroll,
- inHasGrow, inHasFocusBox, inDoubleClickMessage, inTextTraitsID,
- callerLDEFResID, inSuper)
- {
- init () ;
- }
-
- CCustomListBox::CCustomListBox (const CCustomListBox &inOriginal) : LListBox (inOriginal)
- {
- init () ;
- }
-
- CCustomListBox::CCustomListBox(LStream *inStream) : LListBox (inStream)
- {
- init () ;
- }
-
- //----------------------------------------------------------------------------
- // Associate our own LDEF with the list
-
- void CCustomListBox::init (void)
- {
- if (callerLDEFUPP == NULL) // create UPP for LDEF callback
- callerLDEFUPP = NewListDefProc (LDefProc) ;
-
- if ((*mMacListH)->dataBounds.right == 0)
- LAddColumn (1, 0, mMacListH) ; // we want at least one column of data
-
- (*mMacListH)->refCon = (long) callerLDEFUPP ; // put address of callback in refCon
- (*mMacListH)->userHandle = (Handle) this ; // keep a pointer to ourself
- }
-
- //----------------------------------------------------------------------------
- // Get data in and out a selected element of the list
-
- void *CCustomListBox::GetSelection (void *outDescriptor, short *outDescLen) const
- {
- Cell firstSelection = {0, 0};
- if (::LGetSelect(true, &firstSelection, mMacListH))
- { Int16 dataLen = 255;
- ::LGetCell(outDescriptor, outDescLen, firstSelection, mMacListH);
- }
-
- return outDescriptor ;
- }
-
- void CCustomListBox::SetSelection(const void *inDescriptor, const short inDescLen)
- {
- Cell firstSelection = {0, 0};
- if (::LGetSelect(true, &firstSelection, mMacListH) && FocusDraw()) {
- ::LSetCell(inDescriptor, inDescLen, firstSelection, mMacListH);
- }
- }
-
- //----------------------------------------------------------------------------
- // Return a pointer to element data as stored in the list.
- // Hey, this is dangerous, as the cell data can move around, so use with caution
-
- void *CCustomListBox::GetCellPtr (const Cell cell, short *dataLen)
- { short offset, len ;
-
- ::LGetCellDataLocation (&offset, &len, cell, mMacListH) ;
- if (offset < 0) return NULL ;
- if (dataLen) *dataLen = len ;
- Handle h = (*mMacListH)->cells ;
- return (*h)+offset ;
- }
-
- //----------------------------------------------------------------------------
-
- void CCustomListBox::DrawElement (const short lMessage,
- const Boolean lSelect,
- const Rect *lRect,
- const void *lElement,
- const short lDataLen)
-
- // Member function for responding to LDEF calls.
- // Calls DrawElementSelf to draw a list element.
-
- {
- switch (lMessage) {
-
- case lDrawMsg :
- ::EraseRect (lRect) ;
- if (lDataLen == 0)
- break ;
-
- DrawElementSelf (lRect, lElement, lDataLen) ;
-
- if (!lSelect)
- break ;
-
- case lHiliteMsg :
- // Use color hiliting!
- LMSetHiliteMode (LMGetHiliteMode() & ~(1 << hiliteBit)) ;
- ::InvertRect (lRect) ;
- break ;
- }
- }
-
- //----------------------------------------------------------------------------
-
- void CCustomListBox::DrawElementSelf (const Rect *lRect,
- const void *lElement,
- const short lDataLen)
-
- // Draw contents of a single list element on the screen.
- // Default version just draws text; override for other types of data.
-
- {
- ::MoveTo (lRect->left+2, lRect->top+9) ;
- ::DrawText (lElement, 0, lDataLen) ;
- }
-
- //---------------------------------------------------------------------------------------
- // Printing the list box with a custom LDEF does not seem to work as it should
-
- void CCustomListBox::PrintPanelSelf (const PanelSpec& /* inPanel */)
- {
- Point cellSize = (*mMacListH)->cellSize ;
- Rect lRect ;
- Cell lCell = { 0, 0 } ;
- GrafPtr savePort = (**mMacListH).port;
-
- (**mMacListH).port = UQDGlobals::GetCurrentPort();
-
- CalcLocalFrameRect (lRect) ;
-
- lRect.right = lRect.left + cellSize.h ;
- lRect.bottom = lRect.top + cellSize.v ;
-
- for (;;)
- { short lDataOffset, lDataLen ;
-
- ::LGetCellDataLocation (&lDataOffset, &lDataLen, lCell, mMacListH) ;
- if (lDataOffset == -1)
- break ;
-
- LDefProc (lDrawMsg, false, &lRect, lCell, lDataOffset, lDataLen, mMacListH) ;
-
- if (::LNextCell (true, true, &lCell, mMacListH) == false)
- break ;
- lRect.top += cellSize.v ;
- lRect.bottom += cellSize.v ;
- }
-
- (**mMacListH).port = savePort;
-
- ::PenNormal();
- ApplyForeAndBackColors();
-
- CalcLocalFrameRect(lRect);
- ::FrameRect(&lRect);
- }
-
- //----------------------------------------------------------------------------
- // 'self' matches the previously saved 'this'.
-
- static pascal void LDefProc (short lMessage,
- Boolean lSelect,
- Rect *lRect,
- Cell lCell,
- unsigned short lDataOffset,
- unsigned short lDataLen,
- ListHandle lHandle)
-
- // Custom list definition function procedure for CCustomListBox.
- // Called by the LDEF stub; returns control back to class method
- // DrawElement to do the actual drawing.
-
- {
- #pragma unused (lCell)
-
- if ((lMessage == lInitMsg) || // don't bother about these
- (lMessage == lCloseMsg))
- return ;
-
- // restore the application's A5, so that we can access global
- // variables.
- long savedA5 = ::SetCurrentA5() ;
-
- // get the pointer back to 'this'. As the function is no method,
- // and 'this' is a keyword, use 'self' instead.
- CCustomListBox *self = (CCustomListBox*) (*lHandle)->userHandle ;
-
- Handle h = (*self->mMacListH)->cells ;
- char saveState = ::HGetState (h) ;
- ::HLock (h) ;
-
- void *lElement = (void*) (*h + lDataOffset) ;
- self->DrawElement (lMessage, lSelect, lRect, lElement, lDataLen) ;
-
- ::HSetState (h, saveState) ;
- ::SetA5 (savedA5) ;
- }
-
- //----------------------------------------------------------------------------
-